package org.six11.ss.server;

import java.io.PrintWriter;

import org.six11.ss.server.bean.Person;
import org.six11.ss.server.bean.Room;
import org.six11.ss.shared.Message;
import org.six11.util.Debug;
import org.six11.util.adt.MultiState;
import org.six11.util.adt.SynchronizedQueue;

/**
 * This handles a 'quit' command from the Stellasketch applet. This is NOT the same as logging out
 * of the whole web site, which is maintained with a session. Instead, this is simply a notification
 * that the user has finished playing (for now) and we can put them in the offline room.
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class LogoutHandler extends AppletMessageHandler {

  /**
   * @param state
   */
  public LogoutHandler(MultiState state) {
    super(state);
  }

  /**
   * 
   */
  @Override
  public void handle(Message m, String sessionID, PrintWriter out) {
    logout(sessionID);
  }

  public void logout(String sessionID) {
    getLastSeenMap().remove(sessionID);
    
    Person person = getPersonBySession(sessionID);
    if (person == null) {
      bug("I can't find that person in the getPersonBySession map.");
      return; // TODO: must be be able to clean up people who DC abnormally (e.g. network issue)
    }

    // kick the person out of their current room in the normal way
    RoomHandler rh = (RoomHandler) getHandler("room");
    rh.leaveCurrentRoom(person, "logged out");

    // now place them into the 'offline' room.
    Room offline = loadRoom("" + RoomHandler.ROOM_OFFLINE);
    rh.joinRoom(offline, person);

    // clean up the state variables for a player's message queue and session map entry.
    getPersonToMessageQueueMap().remove(person.getId() + "");
    getSessionToPersonMap().remove(sessionID);
    
    bug("Logged out person: " + person.getNick() + " with session " + sessionID);

    // NB: We don't send notification to the user because of a flaw in the way users receive
    // messages. We can't open a connection to the player's machine; we have to wait for them to
    // connect to the PingHandler, and give them a message that way. Unfortunately the PingHandler
    // uses the session-to-person map to make this work, which we just removed.
  }

}
